package cn.dglydrpy.study.j2ee.mq.rabbitmq.producer;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

import java.util.HashMap;
import java.util.Map;
/*
DLX: 全称为Dead-Letter-Exchange，死信交换器。消息在一个队列中变成死信（Dead Letter,默认消费者不可再消费的信息）
之后，被重新发送到一个特殊的交换器（DLX）中，同时，绑定DLX的队列就称为“死信队列”

以下几种情况导致消息变为死信：
1. 消息被拒绝（Basic.Reject/Basic.Nack），并且设置requeue参数为false； 
2. 消息过期；
3. 队列达到最大长度。

它可以处理异常情况下，消息不能够被消费者正确消费(消费者调用了Basic.Nack 或者Basic.Reject)而被置入死信队列中的情况，
后续分析程序可以通过消费这个死信队列中的内容来分析当时所遇到的异常情况，进而可以改善和优化系统

 */
public class DlxProducer {
    public static void main(String[] args) throws Exception {
        ConnectionFactory factory = new ConnectionFactory();
        factory.setUri("amqp://admin:147258aaaaa@192.168.80.131:5672/%2f");

        try (final Connection connection = factory.newConnection();
             final Channel channel = connection.createChannel()) {

//            正常业务的交换器
            channel.exchangeDeclare("ex.biz", "direct", true);
//            声明死信交换器 DLX
            channel.exchangeDeclare("ex.dlx", "direct", true);
//            声明队列做死信队列
            channel.queueDeclare("queue.dlx", true, false, false, null);
//            绑定死信交换器和死信队列
            channel.queueBind("queue.dlx", "ex.dlx", "key.dlx");

            Map<String, Object> arguments = new HashMap<>();
//            指定消息队列中的消息过期时间
            arguments.put("x-message-ttl", 10000);

//            指定过期消息通过死信交换器发送到死信队列，死信交换器的名称，DLX
            arguments.put("x-dead-letter-exchange", "ex.dlx");
//            指定死信交换器的路由键
            arguments.put("x-dead-letter-routing-key", "key.dlx");

            channel.queueDeclare("queue.biz", true, false, false, arguments);
//            绑定业务的交换器和消息队列
            channel.queueBind("queue.biz", "ex.biz", "key.biz");

            channel.basicPublish("ex.biz", "key.biz", null, "ORDER_ID:45789987678".getBytes());

        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}
